# -*- coding: utf-8 -*-
from five import grok
from zope import schema
from plone.directives import form
from zope.interface import Invalid
from plone.app.textfield import RichText
from plone.namedfile.field import NamedImage
from plone.namedfile.interfaces import IImageScaleTraversable
from z3c.relationfield.schema import RelationList, RelationChoice
from plone.formwidget.contenttree import ObjPathSourceBinder,ContentTreeFieldWidget

from Products.bpContents import _
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
from plone.formwidget.autocomplete import AutocompleteFieldWidget
from collective.z3cform.widgets.token_input_widget import TokenInputFieldWidget
from Products.ATVocabularyManager import NamedVocabulary
from collective.gtags.field import Tags
from  plone.folder.interfaces import IOrderableFolder
from collective.plonefinder.widgets.referencewidget import FinderSelectWidget
from Products.bpContents.articulo import IArticulo
from Products.bpContents.galeria import IGaleria
from Products.bpContents.libro import ILibro
from Products.bpContents.evento import IEvento

from zope.component import getMultiAdapter
from plone.memoize.instance import memoize
from Products.ATContentTypes.interface import IATFolder
from Products.CMFDynamicViewFTI.browserdefault import BrowserDefaultMixin

from Acquisition import aq_inner,aq_parent,aq_base

from plone.directives.dexterity import DisplayForm
from Products.bpContents.BaseClassView import BaseClassView
from Products.CMFCore.utils import getToolByName
from Products.bpContents.utils import Utilidades

from lxml import html
from StringIO import StringIO
itemsPorColumna=3


class IDirectorio(form.Schema,IOrderableFolder):
    """El tipo de contenido GALERIA, se utiliza tanto para crear un espacio donde poner fotos, como una sala o como 
    """


    documento =RelationList(
        title=_(u"Destacado"),
        description=_(u"Un articulo para destacar"),
        value_type=RelationChoice(
            source=ObjPathSourceBinder(
                object_provides=(IArticulo.__identifier__,
                                 IGaleria.__identifier__,
                                 ILibro.__identifier__,
                                 IEvento.__identifier__,)
            ),
        ),
        required=False)


class View(DisplayForm,BaseClassView):
    grok.context(IDirectorio)
    grok.require('zope2.View')
    destacadaID=""


    def getDestacado(self):
        """devuelve un articulo destacado, si no se elige
           trae uno de la lista"""

        artDestacado=[]

        if self.context.documento is not None:

            for ref in self.context.documento:
                obj = ref.to_object

                if obj==None:
                    obj=self.getPrimeroListado()
                    artDestacado.append(obj)
                else:
                    dest=dict()
                    dest["maxItems"]    =itemsPorColumna
                    dest["id"]          =obj.id
                    dest["categoria"]   =aq_parent(obj).Title()
                    dest["titulo"]      =obj.Title()
                    dest["tipo"]        =obj.portal_type
                    dest["url"]         =obj.absolute_url()
                    dest["descri"]      =obj.Description

                    if obj.portal_type!="Products.bpContent.libro":
                        dest["imagen"]=self.getIMG("/".join(obj.getPhysicalPath()))
                    else:
                        dest["imagen"]=None

                    artDestacado.append(dest)
        else:


            if len(self.context.getFolderContents())==0:
                return None

            obj=self.getPrimeroListado()
            artDestacado.append(obj)


        if len(artDestacado)>0:
            self.destacadaID=artDestacado[0]["id"]
            return artDestacado
        else:
            catalog = getToolByName(self.context, 'portal_catalog')
            ###aca falta hacer la busqueda por todos los documentos y sacar el ultimo creado
            self.destacadaID=""
            return None

    def getRestoContenidos(self):
        """Devuelve todo lo que viene de data, pero borra el
        destacadao"""
        todosC=self.getCanal()
        indiceC=0


        if todosC:
            for elem in todosC:
                ind=0
                if elem["tipo"]=="carpeta":
                    for item in elem["content"]:
                        if item["id"]==self.destacadaID:
                            del elem["content"][ind]
                        ind+=1



                    if len(elem["content"])==0:
                        ###si el contenedor queda vacio
                        ### lo borro del listado
                        del todosC[indiceC]
                else:
                    if elem["content"]["id"]==self.destacadaID:
                        del todosC[indiceC]

                indiceC+=1
        else:
            return None
        return todosC

    def getPrimeroListado(self):
        """Devuelve el primer objeto de la carpeta que no sea una Folder"""
        count=0
        obj=None
        brains=self.getCanal()
        listaPrimeros=[]

        for elem in brains:
            if elem["tipo"]=="carpeta":
                if len(elem["content"])>0:
                    listaPrimeros.append(elem["content"][0])
            else:
                listaPrimeros.append(elem["content"])
                #obj=self.context.unrestrictedTraverse(elem.getPath())
                #break;
        newlist = sorted(listaPrimeros, key=lambda k: k['date'],reverse=True)
        if len(newlist)>0:
            obj=newlist[0]
        return obj


    def getLocalFolderContent(self):
        self.catalog = getToolByName(self.context, 'portal_catalog')
        self.folder_path = '/'.join(self.context.getPhysicalPath())
        brains= self.catalog.searchResults(path={ "query": self.folder_path ,'depth':1}, sort_on= "modified")
        return brains

    @memoize
    def getCanal(self):
        """devuelve el canal en el que me encuentro"""
        canales=('recreacion','apoyo-a-la-educacion','investigacion','curiosidades','galerias-multimedia',)
        bpUtils=Utilidades()
        resObj      =[]
        carpetPos   =0
        itemPos     =0

        # return myfolder and all child content

        for content in self.getLocalFolderContent():
            contOb  =   self.context.unrestrictedTraverse(content.getPath())
            if content.portal_type in ("Products.bpContents.directorio","Folder","Products.boContents.bookmarkFolder",) and contOb.getExcludeFromNav()==False:
                folderContenidos    =   self.dameContenidos(contOb)
                if  len(folderContenidos)>0:
                    resObj.insert(carpetPos,{
                        "tipo"      :"carpeta",
                        "url"       :contOb.absolute_url(),
                        "titulo"    :contOb.title,
                        "content"   :folderContenidos,
                        "ver_mas"   :self.hayVerMas(contOb),
                        "estado"    :bpUtils.dameEstadoDelObjecto(self.context,contOb)[1],
                        "maxItems"  :itemsPorColumna
                    })
                    carpetPos=carpetPos+1
            else :
                if contOb.getExcludeFromNav()==False or self.destacadaID!=content.id:

                    canD=self.empaqueta(content)
                    resObj.insert((carpetPos+itemPos),{"tipo":"docFinal","content":canD,"maxItems"  :itemsPorColumna})
                    itemPos=itemPos+1

        if len(resObj)>0:
            return resObj
        else:
            return None

    def dameContenidos(self,contOb):
        """devuelve todo lo que se encuetra en una carpeta"""
        ListaTipos=("Products.bpContents.articulo","Products.bpContents.galeria","Products.bpContents.evento","Products.bpContents.libro","Document","Products.bpContents.servicio","Products.bpContents.aviso","File")
        result=[]
        items = self.catalog(portal_type=ListaTipos,
            path={'query': '/'.join(contOb.getPhysicalPath()), 'depth': 1},
            sort_on='modified',
            sort_order='reverse')


        for elem in items:
            elemOb  =   self.context.unrestrictedTraverse(elem.getPath())
            #if self.destacadaID == elem.id:
            #    print elem.id

            if elemOb.getExcludeFromNav() == False and self.destacadaID != elem.id:

                result.append(self.empaqueta(elem))

        return result

    def empaqueta(self,brain):
        """genera un objeto con los datos de un brain """

        bpUtils=Utilidades()
        canD=dict()
        descri=brain.Description
        padre=aq_parent(self.context.unrestrictedTraverse(brain.getPath())).Title()
        if len(descri)>80:
            descri=descri[:descri[:80].rfind(" ")]+"..."

        canD['id']  =brain.id
        canD['titulo']  = brain.Title
        canD['url']     = brain.getPath()
        canD['descri']  = descri
        canD['tipo']    = brain.portal_type
        canD["maxItems"]= itemsPorColumna
        canD["date"]    = brain.modified
        canD["categoria"]=padre
        canD["estado"]=  bpUtils.dameEstadoDelObjecto(self.context,self.context.unrestrictedTraverse(brain.getPath()))[1]
        if brain.portal_type=="Products.bpContents.libro":
            try:
                if brain.portadaLibro!=None:
                    canD['imagen']=brain.portadaLibro
                else:
                    canD['imagen']=False;

            except AttributeError:
                canD['imagen']=False;

        else:
            canD['imagen']=self.getIMG(brain.getPath())


        return canD

    def hayVerMas(self,obj):
        """devulev verdadero o falso si exede en lumero de items por categoria"""
        flag=0
        for elems in obj.getFolderContents():
            if elems.portal_type not in ("Products.bpContents.directorio","Folder"):
                flag=flag+1
        if flag>itemsPorColumna:
            return True
        else:
            return False

    def getIMG(self,ruta):
        catalog = getToolByName(self.context, 'portal_catalog')

        search=catalog(
            path={'query':ruta , 'depth': 1},
            object_provides="Products.ATContentTypes.interfaces.image.IATImage",
            sort_on='modified',
            sort_order='reverse')



        if len(search)>0:
            elemOb=self.context.unrestrictedTraverse(search[0].getPath())
            return elemOb
        else:
            return None




class ListadoDirectorio(grok.View):
    """Vista Dinamica Alternativa de Directorio"""
    grok.context(IATFolder)
    grok.name('listadoDirectorio')
    grok.require('zope2.View')


    def getCanal(self):
        """Devuelve el canal en el que me encuntro
        """

        context = aq_inner(self.context)
        self.catalog = getToolByName(context, 'portal_catalog')
        bpUtils=Utilidades()
        folder_path = '/'.join(context.getPhysicalPath())

        resObj   = []
        carpetPos= 0
        itemPos  = 0
        contents=context.getFolderContents(contentFilter={"sort_on": "modified", "sort_order": "descending"})
        for content in contents:
            contOb  =   self.context.unrestrictedTraverse(content.getPath())
            if content.portal_type in ("Products.bpContents.directorio","Folder","Products.boContents.bookmarkFolder",) and contOb.getExcludeFromNav()==False:
                folderContenidos=self.dameContenidos(contOb)
                bpUtils.dameEstadoDelObjecto(context,contOb)
                if len(folderContenidos)>0:
                    resObj.insert(carpetPos,{
                        "tipo"      : "carpeta",
                        "maxItems"  : itemsPorColumna,
                        "url"       : contOb.absolute_url(),
                        "titulo"    : contOb.title,
                        "contenido" : folderContenidos,
                        "ver_mas"   : self.hayVerMas(contOb),
                        "estado"    : bpUtils.dameEstadoDelObjecto(context,contOb)[1]
                    })
                    carpetPos=carpetPos+1

            else :
                mf=False
                if contOb.portal_type=="Products.bpContents.aviso":
                    mf=True
                elif contOb.getExcludeFromNav()==False:
                    mf=True
                if mf:
                    if content.Title!= '':
                        empaquetado=self.empaqueta(content)
                        resObj.insert((carpetPos+itemPos),{"tipo":"docFinal","objeto":empaquetado,"maxItems"  : itemsPorColumna,})
                        itemPos=itemPos+1




        if len(resObj)>0:
            return resObj
        else:
            return None


    def esListadoConCarpetas(self):
        """Devuelve verdadero si lo que se mustra es un mix de carpetas y archivos"""
        devolver = False

        for elem in self.context.getFolderContents():
            if elem.portal_type in ("Folder", "Products.bpContents.directorio"):
                devolver=True
                break

        return devolver

    def dameContenidos(self,contOb):
        """devuelve todo lo que se encuetra en una carpeta"""
        result=[]
        items = self.catalog(porta_type=("Document","Products.bpContents.articulo","Products.bpContents.evento","Products.bpContents.galeria","Products.bpContents.libro","Products.bpContents.servicio","File","Products.bpContents.aviso"),
            path={'query': "/".join(contOb.getPhysicalPath()), 'depth': 1,},sort_on="modified", sort_order="descending")
        for elem in items:
            elemOb  =   self.context.unrestrictedTraverse(elem.getPath())
            if elemOb.getExcludeFromNav()==False:
                result.append(self.empaqueta(elem))
        return result

    def empaqueta(self,brain):
        """genera un objeto con los datos de un brain """
        bpUtils=Utilidades()
        canD=dict()
        descri=brain.Description

        if len(descri)>80:
            descri=descri[:descri[:80].rfind(" ")]+"..."

        miEstado=bpUtils.dameEstadoDelObjecto(self.context,self.context.unrestrictedTraverse(brain.getPath()))

        canD['titulo']  =   brain.Title
        canD['url']     =   brain.getPath()
        canD['descri']  =   descri
        canD['tipo']    =   brain.portal_type
        canD["maxItems"]=   itemsPorColumna
        canD["estado"]  =   miEstado[1]




        if brain.portal_type=="Products.bpContents.libro":
            try:
                if brain.portadaLibro!=None:
                    canD['imagen']=brain.portadaLibro
                else:
                    canD['imagen']=False;
            except AttributeError:
                canD['imagen']=False;
        elif brain.portal_type=="Document"  or brain.portal_type=="Products.bpContents.aviso"  :
            docuObj=self.context.unrestrictedTraverse(brain.getPath())
            if brain.portal_type=="Products.bpContents.aviso":
                tmpHTML = docuObj.cuerpo.output.decode("utf8")
            else:
                tmpHTML = docuObj.getText().decode("utf8")

            if tmpHTML!="":
                tree=html.document_fromstring(tmpHTML)
                imgs=tree.xpath("//img")
                youts=tree.xpath("//embed")


                if len(imgs)>0:
                    canD['imagen']=imgs[0].attrib["src"]
                else:
                    if len(youts)>0:
                        cadena=youts[0].attrib["src"]
                        idX=cadena[cadena.rfind("/")+1:cadena.rfind("?")]
                        canD['imagen']="http://img.youtube.com/vi/%s/3.jpg" %idX
                    else:
                        canD['imagen']=False
            else:
                canD['imagen']=False
        else:
            canD['imagen']=self.getIMG(brain.getPath())

        if brain.portal_type=="Products.bpContents.galeria":
            objGalPosta=self.context.unrestrictedTraverse(brain.getPath())
            objGal=brain
            canD['imagen']=False
            canD["tipoGal"]  =   objGalPosta.tipoGaleria
            if objGalPosta.tipoGaleria=="Multimedia":
                canD['imagen']=self.getIMG(brain.getPath())
            else:
                if hasattr(objGalPosta.retrato,"filename"):
                    canD['imagen']=objGalPosta.retrato


        return canD

    def hayVerMas(self,obj):
        """devulev verdadero o falso si exede en lumero de items por categoria"""
        flag=0
        for elems in obj.getFolderContents():
            if elems.portal_type not in ("Products.bpContents.directorio","Folder"):
                flag=flag+1
        if flag>itemsPorColumna:
            return True
        else:
            return False


    def getIMG(self,ruta):
        catalog = getToolByName(self.context, 'portal_catalog')
        search=catalog(
            path={'query':ruta , 'depth': 1},
            object_provides="Products.ATContentTypes.interfaces.image.IATImage",
            sort_on='modified',
            sort_order='reverse')

        if len(search)>0:
            imgOnj=self.context.unrestrictedTraverse(search[0].getPath())
            return imgOnj
        else:
            return None